#!/usr/bin/env python
"""The manager proxy will provide an interface to Asterisk AMI and clients"""

import time

class AMI_Message(object):
	"""The generic Asterism AMI message.
	This will include Action, Event and Response message
	"""
	#End of Line token
	EOL = '\r\n'
	#End of Message token
	EOM	= '\r\n\r\n'
	
	def __init__(self,  parameters=None):
		self.parameters = dict()
		self.parameters_list = list() # list of tuples
		if parameters:
			self.add_parameters(parameters)

	def add_parameters(self, parameters):
		self.parameters_list = list(parameters)
		self.parameters.update(dict(self.parameters_list))
			
	def __repr__(self):
		return self.serialize()
	
	def serialize(self):
		"""Build an official string representing the AMI object"""
		clist = []
		for item in self.parameters_list:
			clist.append('%s: %s'%item)
		clist.append(self.EOL)
		action = self.EOL.join(clist)		
		return action

	def get_action_id(self):
		return self.get_key('ActionID')
	
	def get_key (self, key):
		"""Return the value of a key"""
		if self.parameters:
			return self.parameters.get(key)
		else:
			return None

	def set_key(self, key, value):

		self.parameters[key] = value

		new_item = tuple(key,value)
		key_found = False		
		for p in self.parameters_list:
			if p[0] == key:
				index = self.parameters_list.index(p)
				self.parameters_list[index] = new_item
				key_found = True
		if not key_found:
			self.parameters_list.append(new_item)

class IncomingMessage(AMI_Message):
	"""A generic incoming message.
	Incoming Messages are messages being sent from Asterisk to clients. 
	Events and Responses are messages of this type."""
	def __init__(self, raw_content):			
		plist = self.prepare(raw_content)
		AMI_Message.__init__(self, plist)

	def prepare(self, raw_content):
		#construct the raw message in our format.
		lines = raw_content.split(self.EOL)
		plist = []
		for line in lines:
			key, value = line.split(':')
			para = tuple((key,value))
			plist.append(para)
		return plist


class Event(IncomingMessage):
	"""Event message can be asynchronous Event or Synchronous Event
	The asynchronous event will be sent from Asterisk AMI without our requests
	The Synchronous event will be sent from Asterisk AMI as part of AMI response 
	to client's Action"""
	def __init__(self, raw_content = None):
		IncomingMessage.__init__(self, raw_content)

class Response(IncomingMessage):
	"""Response messsage will be sent from Asterisk server following the client's Action """
		
	def __init__(self, raw_content = None):
		IncomingMessage.__init__(self, raw_content)
		self.child_events = []
	#	self.complete = self.is_list()

	# def add_event(self, event):
	# 	self.child_events.append(event)

	# def is_list(self):
	# 	if 'start' in self.get_key('EventList') or 'follow' in self.get_key('Message'):
	# 		return True
	# 	else:
	# 		return False
	
	# def is_complete(self):
	# 	return self._complete		

class OutgoingMessage(AMI_Message):
	"""A generic outgoing message.

	Outgoing Messages are requests being sent to Asterisk. 
	Actions are messages of this type.
	"""
	def __init__(self, parameters=None): 
		AMI_Message.__init__(self, parameters)


class ActionMessage (OutgoingMessage):
	"""Action message is only sent from AMI client to Asterisk AMI"""
	_action_id_ = time.mktime(time.localtime())
	def __init__(self, parameters):		
		OutgoingMessage.__init__(self, parameters)		
	
